﻿using System.Collections;
using System.IO;
using System.Windows.Automation;
using System.Windows.Automation.Peers;
using System.Windows.Controls;
using System.Windows.Input;
using DimensionsHelper.Client.ViewModels;
using DimensionsHelper.Common.Contracts.Services;
using DimensionsHelper.Common.Utils;

namespace DimensionsHelper.Client.Views;

public partial class JsonPathTile
{
    public static readonly DependencyProperty JsonPathProperty = DependencyProperty.Register(
        nameof(JsonPath),
        typeof(string),
        typeof(JsonPathTile),
        new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
            OnJsonPathPropertyChanged));


    public static readonly DependencyProperty OptionalJsonListProperty = DependencyProperty.Register(
        nameof(OptionalJsonList),
        typeof(IList),
        typeof(JsonPathTile),
        new PropertyMetadata(new List<FileInfoViewModel>()));

    static JsonPathTile()
    {
        CommandManager.RegisterClassCommandBinding(typeof(JsonPathTile),
            new CommandBinding(ApplicationCommands.Open, OnOpenJsonFile));
        CommandManager.RegisterClassCommandBinding(typeof(JsonPathTile),
            new CommandBinding(ApplicationCommands.Save, OnSaveJsonFile));
        CommandManager.RegisterClassCommandBinding(typeof(JsonPathTile),
            new CommandBinding(ApplicationCommands.SaveAs, OnSaveAsJsonFile));
    }


    public JsonPathTile()
    {
        InitializeComponent();
    }


    public string JsonPath
    {
        get => (string)GetValue(JsonPathProperty);
        set => SetValue(JsonPathProperty, value);
    }


    public IList OptionalJsonList
    {
        get => (IList)GetValue(OptionalJsonListProperty);
        set => SetValue(OptionalJsonListProperty, value);
    }


    private static async void OnOpenJsonFile(object sender, RoutedEventArgs e)
    {
        if (sender is not JsonPathTile control || 
            await App.GetService<IFilePikerService>()!.PickSingleFileAsync(FileFilters.Json) is not { Length: > 0 } path)
        {
            return;
        }

        control.JsonPath = path;

        AutomationPeer peer = UIElementAutomationPeer.CreatePeerForElement((Button)e.OriginalSource);
        peer.RaiseNotificationEvent(
            AutomationNotificationKind.Other,
            AutomationNotificationProcessing.ImportantMostRecent,
            "Select Json File",
            "ButtonClickedActivity");
    }


    private static async void OnSaveJsonFile(object sender, RoutedEventArgs e)
    {
        if (sender is not JsonPathTile tile)
        {
            return;
        }

        await tile.SaveJson(false);
        AutomationPeer peer = UIElementAutomationPeer.CreatePeerForElement((Button)e.OriginalSource);
        peer.RaiseNotificationEvent(
            AutomationNotificationKind.Other,
            AutomationNotificationProcessing.ImportantMostRecent,
            "Save Json File",
            "ButtonClickedActivity");
    }


    private static async void OnSaveAsJsonFile(object sender, RoutedEventArgs e)
    {
        if (sender is not JsonPathTile tile)
        {
            return;
        }

        await tile.SaveJson(true);
        AutomationPeer peer = UIElementAutomationPeer.CreatePeerForElement((Button)e.OriginalSource);
        peer.RaiseNotificationEvent(
            AutomationNotificationKind.Other,
            AutomationNotificationProcessing.ImportantMostRecent,
            "Save Json File As",
            "ButtonClickedActivity");
    }


    private void LoadJson()
    {
        if (DataContext is not JsonLoaderViewModelBase jsonLoader)
        {
            return;
        }

        if (jsonLoader.LoadJson())
        {
            jsonLoader.AddHistoricalJson(JsonPath);
        }
    }


    private async Task SaveJson(bool saveAs)
    {
        if (DataContext is not JsonLoaderViewModelBase jsonLoader)
        {
            return;
        }

        if (await jsonLoader.SaveJson(saveAs))
        {
            jsonLoader.AddHistoricalJson(JsonPath);
        }
    }


    private static void OnJsonPathPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        JsonPathTile? tile = (JsonPathTile)d;
        string json = (string)e.NewValue;

        if (!File.Exists(json) || (!json.EndsWith(".json", StringComparison.OrdinalIgnoreCase) &&
                                   !json.EndsWith(".jsonc", StringComparison.OrdinalIgnoreCase)))
        {
            return;
        }

        tile.LoadJson();
    }
}